package com.authine.cloudpivot.web.api.secondopen.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.web.api.secondopen.dao.SameRoadBusinessTravelMapper;
import com.authine.cloudpivot.web.api.secondopen.domain.DingDingUser;
import com.authine.cloudpivot.web.api.secondopen.domain.NoteFlightOrderPushBack;
import com.authine.cloudpivot.web.api.secondopen.domain.NoteStatementPageList;
import com.authine.cloudpivot.web.api.secondopen.domain.SameRoadApplyOrderSyncMaintain;
import com.authine.cloudpivot.web.api.secondopen.service.SameRoadBusinessTravelService;
import com.authine.cloudpivot.web.api.secondopen.service.SyncService;
import com.authine.cloudpivot.web.api.secondopen.utils.JsonValidator;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * @Author: brookpeng
 * @Date: 2021/12/13 17:11
 */
@Service
public class SameRoadBusinessTravelServiceImpl implements SameRoadBusinessTravelService {
    private static final Logger log = LoggerFactory.getLogger(SameRoadBusinessTravelServiceImpl.class);

    private static String account = "c4ff7f1429284feebca04f16c6b9a2da";
    private static String password = "HJtWr187ONIUEm6sQgpw";
    private static String secret = "8vCLNVibnpLcODxx";

    @Autowired
    private SyncService syncService;

    @Autowired
    private SameRoadBusinessTravelMapper sameRoadBusinessTravelMapper;

    @Override
    public String syncEmployeeInfo() {
        // 获取人员信息
        List<DingDingUser> userInfo = syncService.getUserInfo();
        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());

        // 人员信息同步计数
        Integer count = 0;
        for (DingDingUser dingDingUser : userInfo) {

//            if (!"丁威".equals(dingDingUser.getName())) {
//                continue;
//            }

            // 员工信息预处理
            // 拆分姓名
            String name = dingDingUser.getName();
            int length = name.length();
            String part1Name = "";
            String part2Name = "";
            if (length == 2) {
                part1Name = name.substring(0, 1);
                part2Name = name.substring(1);
            } else if (length == 3) {
                part1Name = name.substring(0, 1);
                part2Name = name.substring(1);
            } else if (length == 4) {
                part1Name = name.substring(0, 2);
                part2Name = name.substring(2);
            } else {
                switch (name) {
                    case "木地本達也":
                        part1Name = name.substring(0, 3);
                        part2Name = name.substring(3);
                        break;
                }
                int i = name.indexOf("\b");
                if (i >= 0) {
                    part1Name = name.substring(0, i);
                    part2Name = name.substring(i + 1);
                }
            }

            // testStart
//            part1Name = "胡";
//            part2Name = "其满";
//            dingDingUser.setMobile("15050276954");
//            dingDingUser.setJobnumber("1234567");
//            dingDingUser.setEmail("yeahqm@163.com");
//            dingDingUser.setIdcard("340825198104193819");
//            part1Name = "彭";
//            part2Name = "一凡";
//            dingDingUser.setMobile("13940992795");
//            dingDingUser.setJobnumber("01194506611624116238");
//            dingDingUser.setEmail("752010921@qq.com");
//            dingDingUser.setIdcard("210603199212070513");
            // testEnd

            // 参数准备
            /*外部员工ID*/
            String outEmployeeId = dingDingUser.getJobnumber();
            /*员工类型(0员工 1因公客人 2因私客人)*/
            String employeeType = "0";
            /*中文姓*/
            String surName = part1Name;
            /*中文名*/
            String givenName = part2Name;
            /*性别(0.女 1.男)*/
            Integer gender = dingDingUser.getSex();
            /*手机号*/
            String mobile = dingDingUser.getMobile();
            /*邮箱*/
            String email = dingDingUser.getEmail();
            /*身份证号*/
            String idCard = dingDingUser.getIdcard();
            /*预订类别(0仅限本人 1本人+同事 2本人+因公客人 3本人+同事+因公客人)*/
            Integer reservationType = 0;
            /*职位名称*/
            String positionName = dingDingUser.getJbmc();
            /*职级名称(职级与差标关联，需要必传)*/
            String positionLevelName = dingDingUser.getJbbm();
            /*部门名称*/
            String departName = dingDingUser.getDeptname();
            /*在职状态(0离职 1在职)*/
            Integer workingState = dingDingUser.getWorkingstate();
            /*证件类型(证件类型 默认1身份证1:身份证 2:公务护照 3:普通护照 4:港澳通行证 5:台胞证 6:回乡证 7:军人证 8:海员证 9:其他 10:台湾通行证)*/
            Integer credentialType = 1;
            /*是否允许新增(是否允许预订时新增乘客资料 0不允许 1允许 非必传)*/
            Integer addTravellerAllowed = 0;
            /*员工工号*/
            String employeeCode = dingDingUser.getJobnumber();
            /*成本中心*/
            String costCenter = dingDingUser.getDeptname();

            String postData = "{\n" +
                    "  \"accessToken\": \"" + accountToken + "\",\n" +
                    "  \"isEncrypt\": " + false + ",\n" +
                    "  \"random\": \"" + random + "\",\n" +
                    "  \"timestamp\": \"" + timestamp + "\",\n" +
                    "  \"param\": {\n" +
                    "    \"outEmployeeId\": \"" + outEmployeeId + "\",\n" +
                    "    \"employeeType\": " + employeeType + ",\n" +
                    "    \"surName\": \"" + surName + "\",\n" +
                    "    \"givenName\": \"" + givenName + "\",\n" +
                    "    \"gender\": " + gender + ",\n" +
                    "    \"mobile\": \"" + mobile + "\",\n" +
                    "    \"email\": \"" + email + "\",\n" +
                    "    \"idCard\": \"" + idCard + "\",\n" +
                    "    \"reservationType\": " + reservationType + ",\n" +
                    "    \"positionName\": \"" + positionName + "\",\n" +
                    "    \"positionLevelName\": \"" + positionLevelName + "\",\n" +
                    "    \"departName\": \"" + departName + "\",\n" +
                    "    \"workingState\": " + workingState + ",\n" +
                    "    \"credentialType\": "+credentialType+",\n" +
                    "    \"addTravellerAllowed\": "+addTravellerAllowed+",\n" +
                    "    \"employeeCode\": \""+employeeCode+"\",\n" +
                    "    \"costCenter\": \""+costCenter+"\",\n" +
                    "  }\n" +
                    "}";

            // 先将post提交的数据原文算出md5
            String postDataMd5 = getMd5(postData);

            // 再计算 sign
            String sign = getMd5(postDataMd5 + secret);

            // get方式提交sign
            String url = "http://api.qa.dttrip.cn/openapi/api/Employee/SyncEmployeeInfo?sign=" + sign;

            log.info("▼▼▼同程商旅人员信息同步开始▼▼▼，姓名:{}，工号:{}▼▼▼", name, outEmployeeId);

            // 请求接口
            String result = postData(postData, url);

            Map resultMap = JSON.parseObject(result);
            if (resultMap != null) {
                Map dataMap = (Map) resultMap.get("data");
                String errorMessage = (String) resultMap.get("errorMessage");
                if (dataMap != null) {
                    String employeeId = (String) dataMap.get("employeeId");
                    boolean syncResult = (boolean) resultMap.get("success");
                    if (syncResult) {
                        count++;
//                SameRoadApplyOrderSyncMaintain sameRoadApplyOrderSyncMaintain = this.convertCurrencyInfo(sequenceNo, travelApplyNo);
//                int resultNum = sameRoadBusinessTravelMapper.insertSyncResult(sameRoadApplyOrderSyncMaintain, sameRoadApplyOrderSyncTableName);
                        log.info("▲▲▲同程商旅差旅单同步成功▲▲▲，同程单号:{}▲▲▲", employeeId + " : " + errorMessage);
                    } else {
                        String errorCode = (String) resultMap.get("errorCode");
                        log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{}▲▲▲", errorCode + " : " + errorMessage);
                    }
                } else {
                    String errorCode = (String) resultMap.get("errorCode");
                    log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{}▲▲▲", errorCode + " : " + errorMessage);
                }
            } else {
                log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{同程请求异常}▲▲▲");
            }
        }
        log.info("※※※人员信息同步影响记录:{}条※※※", count);

        return count.toString();
    }

    @Override
    public String syncTravelApplyOrder(String tableName, String sequenceNo, String subTableName, String sameRoadApplyOrderSyncTableName) {

        Map<String, Object> ccsqdInfo = sameRoadBusinessTravelMapper.getCcsqdInfo(tableName, sequenceNo);
        String id = (String) ccsqdInfo.get("id");
        List<Map<String, Object>> ccsqdSubTable = sameRoadBusinessTravelMapper.getCcsqdSubTable(subTableName, id);
        // 出差申请单状态判断
        String sequenceStatus = (String) ccsqdInfo.get("sequenceStatus");

        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());

        // 参数准备
        /*外部差旅单单号*/
        String outTravelApplyNo = (String) ccsqdInfo.get("sequenceNo");
        /*差旅类型(1：普通差旅；2：福利差旅)*/
        Integer travelApplyType = 1;
        /*差旅单申请时间*/
        Timestamp travelApplyTime = (Timestamp) ccsqdInfo.get("createdTime");
        /*差旅单更新时间*/
        Timestamp travelUpdateTime = (Timestamp) ccsqdInfo.get("modifiedTime");
        /*操作类型(1：新增，2：更新)*/
        Integer operationType = 1;
        /*外部员工ID（申请人）*/
        String outEmployeeId = (String) ccsqdInfo.get("employeeNo");
        /*差旅内容*/
        String travelDescription = (String) ccsqdInfo.get("ccsy");
        /*可预订产品(可预订产品类型，逗号分隔。1：国内机票 ，2：国际机票 ，3：国内酒店 ，4：海外酒店 ，5：火车票 ，6：用车)*/
        String jtgj = (String) ccsqdInfo.get("jtgj");
        boolean isPlane = jtgj.contains("飞机");
        String bookableProducts = "3,5,6";
        if (isPlane) {
            bookableProducts = "1,2,3,4,5,6";
        }
        /*差旅单状态(1 通过 2 作废 )*/
        Integer status = 2;
        if ("COMPLETED".equals(sequenceStatus)) {
            status = 1;
        }
        /*差旅内容*/
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\t\t\"itemList\": [");
        for (int i = 0; i < ccsqdSubTable.size(); i++) {
            Map<String, Object> stringObjectMap = ccsqdSubTable.get(i);
            /*差旅开始时间*/
            Timestamp startDate = (Timestamp) stringObjectMap.get("startDate");
            /*差旅结束时间*/
            Timestamp endDate = (Timestamp) stringObjectMap.get("endDate");
            /*差旅出发地*/
            String departCityStr = (String) stringObjectMap.get("departCity");
            Map departCityMap = JSON.parseObject(departCityStr);
            String departCity = (String) departCityMap.get("cityName");
            /*差旅目的地*/
            String arriveCityStr = (String) stringObjectMap.get("arriveCity");
            Map arriveCityMap = JSON.parseObject(arriveCityStr);
            String arriveCity = (String) arriveCityMap.get("cityName");
            stringBuilder.append("{\n" +
                    "\t\t\t\"startDate\": \"" + startDate + " \",\n" +
                    "\t\t\t\"endDate\": \"" + endDate + " \",\n" +
                    "\t\t\t\"departCity\": \"" + departCity + "\",\n" +
                    "\t\t\t\"arriveCity\": \"" + arriveCity + "\"\n" +
                    "\t\t}");
            int j = i + 1;
            if (j < ccsqdSubTable.size()) {
                stringBuilder.append(",");
            }
        }
        stringBuilder.append("],\n");
        /*差旅人姓名*/
        String name = (String) ccsqdInfo.get("name");
        /*亲属关系(0:内部员工，1:配偶，2:子女，3:父母，4:面试候选人，5:实习生，6:外部宾客； 注意数据类型)*/
        Integer relation = 0;
        /*人员类型(0成人 1儿童 2 婴儿)*/
        Integer passengerType = 0;
        /*使用差旅单审批规则(0.不使用 1.无需审批 2.超标审批 3.需要审批)*/
        Integer approveRuleType = 1;

        String postData = "{\n" +
                "\t\"accessToken\": \"" + accountToken + "\",\n" +
                "\t\"isEncrypt\": " + false + ",\n" +
                "\t\"random\": \"" + random + "\",\n" +
                "\t\"timestamp\": \"" + timestamp + "\",\n" +
                "\t\"param\": {\n" +
                "\t\t\"outTravelApplyNo\": \"" + outTravelApplyNo + "\",\n" +
                "\t\t\"travelApplyType\": " + travelApplyType + ",\n" +
                "\t\t\"status\": " + status + ",\n" +
                "\t\t\"travelApplyTime\": \"" + travelApplyTime + "\",\n" +
                "\t\t\"travelUpdateTime\": \"" + travelUpdateTime + "\",\n" +
                "\t\t\"operationType\": " + operationType + ",\n" +
                "\t\t\"outEmployeeId\": \"" + outEmployeeId + "\",\n" +
                "\t\t\"travelDescription\": \"" + travelDescription + "\",\n" +
                "\t\t\"bookableProducts\": \" " + bookableProducts + "\",\n" +
                "\t\t\"bookableQuantity\": -1,\n" +
                "\t\t\"roomBookableQuantity\": -1,\n" +
                "\t\t\"travelPolicyCode\": \"\",\n" +
                "\t\t\"redirectUrl\": \"\",\n" +
//                "\t\t\"itemList\": [{\n" +
//                "\t\t\t\"startDate\": \"2021-04-20 \",\n" +
//                "\t\t\t\"endDate\": \"2021-04-25 \",\n" +
//                "\t\t\t\"departCity\": \"北京\",\n" +
//                "\t\t\t\"arriveCity\": \"上海\",\n" +
//                "\t\t\t\"otherCity\": \"南京\",\n" +
//                "\t\t\t\"baseCity\": \"北京\"\n" +
//                "\t\t}],\n" +
                stringBuilder.toString() +
                "\t\t\"personList\": [{\n" +
                "\t\t\t\"name\": \"" + name + "\",\n" +
                "\t\t\t\"relation\": " + relation + ",\n" +
                "\t\t\t\"passengerType\": " + passengerType + ",\n" +
                "\t\t\t\"credentialType\": 1,\n" +
                "\t\t\t\"credentialNo\": \"\",\n" +
                "\t\t\t\"credentialExpiredDate\": \"\",\n" +
                "\t\t\t\"nationality\": \"\",\n" +
                "\t\t\t\"birthday\": \"\",\n" +
                "\t\t\t\"mobilePhone\": \"\",\n" +
                "\t\t\t\"outEmployeeId\": \"" + outEmployeeId + "\"\n" +
//                "\t\t\t\"hotelTravelPolicy\": {\n" +
//                "\t\t\t\t\"detail\": {\n" +
//                "\t\t\t\t\t\"cityTravelPolicyList\": [{\n" +
//                "\t\t\t\t\t\t\"cityName\": \"上海\",\n" +
//                "\t\t\t\t\t\t\"maxPrice\": 500,\n" +
//                "\t\t\t\t\t\t\"violationStrategy\": 1\n" +
//                "\t\t\t\t\t}],\n" +
//                "\t\t\t\t\t\"otherCityTravelPolicy\": {\n" +
//                "\t\t\t\t\t\t\"maxPrice\": 300,\n" +
//                "\t\t\t\t\t\t\"violationStrategy\": 2\n" +
//                "\t\t\t\t\t},\n" +
//                "\t\t\t\t\t\"onePeopleFloating\": {\n" +
//                "\t\t\t\t\t\t\"type\": 0,\n" +
//                "\t\t\t\t\t\t\"value\": 0\n" +
//                "\t\t\t\t\t},\n" +
//                "\t\t\t\t\t\"manyPeopleFloating\": {\n" +
//                "\t\t\t\t\t\t\"type\": 0,\n" +
//                "\t\t\t\t\t\t\"value\": 0\n" +
//                "\t\t\t\t\t},\n" +
//                "\t\t\t\t\t\"basePriceType\": 2,\n" +
//                "\t\t\t\t\t\"roomPriceType\": 1\n" +
//                "\t\t\t\t}\n" +
//                "\t\t\t\t\"policyCode\": \"\"\n" +
//                "\t\t\t}\n" +
                "\t\t}],\n" +
//                "\t\t\"preTravelPolicyList\": [{\n" +
//                "\t\t\t\"policyCode\": \"\",\n" +
//                "\t\t\t\"productTypeId\": 0\n" +
//                "\t\t}],\n" +
//                "\t\t\"submitItemList\": [{\n" +
//                "\t\t\t\t\"code\": \"Objective\",\n" +
//                "\t\t\t\t\"content\": \"出差类型的值\"\n" +
//                "\t\t\t},\n" +
//                "\t\t\t{\n" +
//                "\t\t\t\t\"code\": \"CostCenter\",\n" +
//                "\t\t\t\t\"content\": \"支付公司的值\"\n" +
//                "\t\t\t},\n" +
//                "\t\t\t{\n" +
//                "\t\t\t\t\"code\": \"Project\",\n" +
//                "\t\t\t\t\"content\": \"项目名称的值\"\n" +
//                "\t\t\t}\n" +
//                "\t\t],\n" +
//                "\t\t\"approverList\": [{\n" +
//                "\t\t\t\t\"outEmployeeId\": \"test002\", //test002需要提前同步到系统当中\n" +
//                "\t\t\t\t\"approverType\": 0,\n" +
//                "\t\t\t\t\"approverGrade\": 1\n" +
//                "\t\t\t},\n" +
//                "\t\t\t{\n" +
//                "\t\t\t\t\"outEmployeeId\": \"test003\", //test003需要提前同步到系统当中\n" +
//                "\t\t\t\t\"approverType\": 0,\n" +
//                "\t\t\t\t\"approverGrade\": 2\n" +
//                "\t\t\t}\n" +
//                "\t\t],\n" +
//                "\t\t\"approveRuleType\": " + approveRuleType + ",\n" +
                "\t\t\"carBookableQuantity\": 0\n" +
                "\t}\n" +
                "}";

        // 先将post提交的数据原文算出md5
        String postDataMd5 = getMd5(postData);

        // json格式检测(validate = true表示正确)
        JsonValidator jsonValidator = new JsonValidator();
        boolean validate = jsonValidator.validate(postData);
        if (!validate) {
            log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postData);
            return "json is not legal";
        }

        // 再计算 sign
        String sign = getMd5(postDataMd5 + secret);

        // get方式提交sign
        String url = "http://api.qa.dttrip.cn/openapi/api/TravelApplyOrder/ApplyOrderSync?sign=" + sign;

        log.info("▼▼▼同程商旅差旅单同步开始▼▼▼，OA单号:{}▼▼▼", sequenceNo);

        // 请求接口
        String result = postData(postData, url);

        Map resultMap = JSON.parseObject(result);
        if (resultMap != null) {
            Map dataMap = (Map) resultMap.get("data");
            String errorMessage = (String) resultMap.get("errorMessage");
            if (dataMap != null) {
                String travelApplyNo = (String) dataMap.get("travelApplyNo");
                boolean syncResult = (boolean) resultMap.get("success");
                if (syncResult) {
                    SameRoadApplyOrderSyncMaintain sameRoadApplyOrderSyncMaintain = this.convertCurrencyInfo(sequenceNo, travelApplyNo);
                    int resultNum = sameRoadBusinessTravelMapper.insertSyncResult(sameRoadApplyOrderSyncMaintain, sameRoadApplyOrderSyncTableName);
                    log.info("※※※差旅单同步影响记录:{}条※※※", resultNum);
                    log.info("▲▲▲同程商旅差旅单同步成功▲▲▲，同程单号:{}▲▲▲", travelApplyNo + " : " + errorMessage);
                } else {
                    String errorCode = (String) resultMap.get("errorCode");
                    log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{}▲▲▲", errorCode + " : " + errorMessage);
                }
            } else {
                String errorCode = (String) resultMap.get("errorCode");
                log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{}▲▲▲", errorCode + " : " + errorMessage);
            }
        } else {
            log.info("▲▲▲同程商旅差旅单同步失败▲▲▲，异常信息:{同程请求异常}▲▲▲");
        }

        return result;
    }

    @Override
    public String sameRoadAccountCheck(Integer pageIndex, Integer pageSize, String beginDate, String endDate, String tableName) {

        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());

        String postData = "{\n" +
                "  \"accessToken\": \"" + accountToken + "\",\n" +
                "  \"isEncrypt\": " + false + ",\n" +
                "  \"random\": \"" + random + "\",\n" +
                "  \"timestamp\": \"" + timestamp + "\",\n" +
                "  \"param\": {\n" +
                "    \"pageIndex\": " + pageIndex + ",\n" +
                "    \"pageSize\": " + pageSize + ",\n" +
                "    \"beginDate\": \"" + beginDate + "\",\n" +
                "    \"endDate\": \"" + endDate + "\"\n" +
                "  }\n" +
                "}";

        // 先将post提交的数据原文算出md5
        String postDataMd5 = getMd5(postData);

        // json格式检测(validate = true表示正确)
        JsonValidator jsonValidator = new JsonValidator();
        boolean validate = jsonValidator.validate(postData);
        if (!validate) {
            log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postData);
            return "json is not legal";
        }

        // 再计算 sign
        String sign = getMd5(postDataMd5 + secret);

        // get方式提交sign
        String url = "http://api.qa.dttrip.cn/openapi/api/Order/QueryOnlineStatementPageList?sign=" + sign;

        // 请求接口
        String result = postData(postData, url);

        JSONObject jsonObject = JSON.parseObject(result);
        if (jsonObject != null) {
            JSONObject data = jsonObject.getJSONObject("data");
            String errorMessage = jsonObject.getString("errorMessage");
            if (data != null) {
                double totalPayAmount = data.getDouble("totalPayAmount");
                boolean syncResult = jsonObject.getBoolean("success");
                if (syncResult) {
                    JSONArray onlineStatementList = data.getJSONArray("onlineStatementList");
                    int resNum = 0;
                    if (CollectionUtils.isNotEmpty(onlineStatementList)) {
                        List<NoteStatementPageList> noteStatementPageLists = new ArrayList<>();
                        int size = onlineStatementList.size();
                        for (int i = 0; i < size; i++) {
                            JSONObject subJsonObject = onlineStatementList.getJSONObject(i);
                            NoteStatementPageList noteStatementPageList = new NoteStatementPageList();
                            // 账单总金额
                            noteStatementPageList.setTotalPayAmount(BigDecimal.valueOf(totalPayAmount));
                            // 对账单编码
                            noteStatementPageList.setStatementCode(subJsonObject.getString("statementCode"));
                            // 周期开始时间
                            noteStatementPageList.setBeginDate(subJsonObject.getString("beginDate"));
                            // 周期结束时间
                            noteStatementPageList.setEndDate(subJsonObject.getString("endDate"));
                            // 最晚核对时间
                            noteStatementPageList.setLatestCheckDate(subJsonObject.getString("latestCheckDate"));
                            // 是否过期说明
                            noteStatementPageList.setOverDueRemark(subJsonObject.getString("overDueRemark"));
                            // 待付款
                            Double payAmount = subJsonObject.getDouble("payAmount");
                            noteStatementPageList.setPayAmount(BigDecimal.valueOf(payAmount));
                            noteStatementPageLists.add(noteStatementPageList);
                        }
                        if (CollectionUtils.isNotEmpty(noteStatementPageLists)) {
                            resNum = sameRoadBusinessTravelMapper.insertStatementPageList(noteStatementPageLists, tableName);
                        }

                    }
                    log.info("※※※{}至{}日，总待付款:{}", beginDate, endDate, totalPayAmount);
                    log.info("※※※数据影响条数:{}", resNum);
                } else {
                    String errorCode = (String) jsonObject.get("errorCode");
                    log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                }
            } else {
                String errorCode = (String) jsonObject.get("errorCode");
                log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
            }
        } else {
            log.info("❌❌❌获取对账单列表失败，异常信息:{请求异常}❌❌❌");
        }

        return result;
    }

    @Override
    public String queryOnlineStatementFlightDetailPageList(String statementCode, String StatementStatus) {

        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());
        Integer pageIndex = 1;
        Integer pageSize = 10;

        String result = "";
        Integer pageCount = 0;
        boolean isFirst = true;
        do {
            if (isFirst) {
                isFirst = false;
            } else {
                pageIndex++;
            }
            String postData = "" +
                    "{\n" +
                    "  \"accessToken\": \"" + accountToken + "\",\n" +
                    "  \"isEncrypt\": " + false + ",\n" +
                    "  \"random\": \"" + random + "\",\n" +
                    "  \"timestamp\": \"" + timestamp + "\",\n" +
                    "  \"param\": {\n" +
                    "    \"tickerNo\": \"\",\n" +
                    "    \"pageIndex\": " + pageIndex + ",\n" +
                    "    \"pageSize\": " + pageSize + ",\n" +
                    "    \"statementCode\": \"" + statementCode + "\",\n" +
                    "    \"statementStatus\": [\n" +
                    "      " + 0 + ",\n" +
                    "      " + 1 + ",\n" +
                    "      " + 2 + "\n" +
                    "    ],\n" +
                    "    \"orderSerialNo\": \"\",\n" +
                    "    \"passengerName\": \"\",\n" +
                    "    \"passengerDepartment\": \"\",\n" +
                    "    \"passengerCostCenter\": \"\",\n" +
                    "    \"reserveManName\": \"\",\n" +
                    "    \"reserveManDepartment\": \"\",\n" +
                    "    \"reserveManCostCenter\": \"\",\n" +
                    "    \"enterAccountBegin\": \"\",\n" +
                    "    \"enterAccountEnd\": \"\",\n" +
                    "    \"bookingBegin\": \"\",\n" +
                    "    \"bookingEnd\": \"\",\n" +
                    "    \"outApplayOrderNo\": \"\"\n" +
                    "  }\n" +
                    "}";

            // 先将post提交的数据原文算出md5
            String postDataMd5 = getMd5(postData);

            // json格式检测(validate = true表示正确)
            JsonValidator jsonValidator = new JsonValidator();
            boolean validate = jsonValidator.validate(postData);
            if (!validate) {
                log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postData);
                return "json is not legal";
            }

            // 再计算 sign
            String sign = getMd5(postDataMd5 + secret);

            // get方式提交sign
            String url = "http://api.qa.dttrip.cn/openapi/api/Order/QueryOnlineStatementFlightDetailPageList?sign=" + sign;

            // 请求接口
            result = postData(postData, url);

            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject != null) {
                JSONObject data = jsonObject.getJSONObject("data");
                String errorMessage = (String) jsonObject.get("errorMessage");
                if (data != null) {
                    JSONArray statementOrderList = data.getJSONArray("statementOrderList");
                    JSONObject pageInfo = data.getJSONObject("pageInfo");
                    pageCount = pageInfo.getInteger("pageCount");
                    boolean syncResult = (boolean) jsonObject.get("success");
                    if (syncResult) {
                        int size = statementOrderList.size();
                        for (int i = 0; i < size; i++) {
                            JSONObject subJsonObject = statementOrderList.getJSONObject(i);
                        }
                    } else {
                        String errorCode = (String) jsonObject.get("errorCode");
                        log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                    }
                } else {
                    String errorCode = (String) jsonObject.get("errorCode");
                    log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                }
            } else {
                log.info("❌❌❌获取对账单列表失败，异常信息:{请求异常}❌❌❌");
            }
        } while (pageIndex < pageCount);

        return result;
    }

    @Override
    public String queryOnlineStatementTrainDetailPageList(String statementCode, String statusList) {

        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());

        String postData = "" +
                "{\n" +
                "  \"accessToken\": \"" + accountToken + "\",\n" +
                "  \"isEncrypt\": " + false + ",\n" +
                "  \"random\": \"" + random + "\",\n" +
                "  \"timestamp\": \"" + timestamp + "\",\n" +
                "  \"param\": {\n" +
                "    \"pageIndex\": " + 0 + ",\n" +
                "    \"pageSize\": " + 0 + ",\n" +
                "    \"statementCode\": \"" + statementCode + "\",\n" +
                "    \"statementStatus\": [\n" +
                "      " + 0 + ",\n" +
                "      " + 1 + ",\n" +
                "      " + 2 + "\n" +
                "    ],\n" +
                "    \"orderSerialNo\": \"\",\n" +
                "    \"passengerName\": \"\",\n" +
                "    \"passengerDepartment\": \"\",\n" +
                "    \"passengerCostCenter\": \"\",\n" +
                "    \"reserveManName\": \"\",\n" +
                "    \"reserveManDepartment\": \"\",\n" +
                "    \"reserveManCostCenter\": \"\",\n" +
                "    \"enterAccountBegin\": \"\",\n" +
                "    \"enterAccountEnd\": \"\",\n" +
                "    \"bookingBegin\": \"\",\n" +
                "    \"bookingEnd\": \"\",\n" +
                "    \"outApplayOrderNo\": \"\"\n" +
                "  }\n" +
                "}";

        // 先将post提交的数据原文算出md5
        String postDataMd5 = getMd5(postData);

        // json格式检测(validate = true表示正确)
        JsonValidator jsonValidator = new JsonValidator();
        boolean validate = jsonValidator.validate(postData);
        if (!validate) {
            log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postData);
            return "json is not legal";
        }

        // 再计算 sign
        String sign = getMd5(postDataMd5 + secret);

        // get方式提交sign
        String url = "http://api.qa.dttrip.cn/openapi/api/Order/QueryOnlineStatementTrainDetailPageList?sign=" + sign;

        // 请求接口
        String result = postData(postData, url);

        Map resultMap = JSON.parseObject(result);
        if (resultMap != null) {
            Map dataMap = (Map) resultMap.get("data");
            String errorMessage = (String) resultMap.get("errorMessage");
            if (dataMap != null) {
                String TotalPayAmount = (String) dataMap.get("TotalPayAmount");
                boolean syncResult = (boolean) resultMap.get("success");
                if (syncResult) {
//                    log.info("※※※{}至{}日，总待付款:{}", beginDate, endDate, TotalPayAmount);
                } else {
                    String errorCode = (String) resultMap.get("errorCode");
                    log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                }
            } else {
                String errorCode = (String) resultMap.get("errorCode");
                log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
            }
        } else {
            log.info("❌❌❌获取对账单列表失败，异常信息:{请求异常}❌❌❌");
        }

        return result;
    }

    /**
     * 机票数据回推记录逻辑
     * @param jsonObject
     * @return
     */
    @Override
    public int noteFlightOrder(JSONObject jsonObject, String tableName) {

        NoteFlightOrderPushBack noteFlightOrderPushBack = makeNoteFlightOrderPushBackModel();
        JSONObject notifyData = jsonObject.getJSONObject("notifyData");
        JSONObject data = notifyData.getJSONObject("data");
        JSONObject orderDetails = data.getJSONObject("orderDetails");
        // 订单号
        noteFlightOrderPushBack.setOrderSerialNo(orderDetails.getString("orderSerialNo"));
        // 退改前外部订单号
        noteFlightOrderPushBack.setParentOrderSerialNo(orderDetails.getString("parentOrderSerialNo"));
        // 员工ID
        noteFlightOrderPushBack.setOutEmployeeId(orderDetails.getString("outEmployeeId"));
        // 订单状态
        noteFlightOrderPushBack.setOrderStatusText(orderDetails.getString("orderStatusText"));
        // 最晚出票时间
        noteFlightOrderPushBack.setTicketOutLimitTime(orderDetails.getString("ticketOutLimitTime"));
        // 支付状态 0 未付 1已付
        Integer payStatus = orderDetails.getInteger("payStatus");
        if (0 == payStatus) {
            noteFlightOrderPushBack.setPayStatus("未付");
        } else {
            noteFlightOrderPushBack.setPayStatus("已付");
        }
        // 订单总价
        noteFlightOrderPushBack.setTotalPrice(orderDetails.getBigDecimal("totalPrice"));
        sameRoadBusinessTravelMapper.insertFlightOrderPushBack(noteFlightOrderPushBack, tableName);
        return 0;
    }

    @Override
    public int saveFlightOrderList() {

        // 获取token
        String accountToken = getAccessToken();

        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());
        Integer pageIndex = 1;
        Integer pageSize = 10;

        String result = "";
        String resultSub = "";
        Integer pageCount = 0;
        boolean isFirst = true;
        /**
         * 因环新安全策略限制，采用主动查询方式（同程默认为推送方式），每一种产品（飞机、火车、酒店、用车）需要多查询一个接口（列表+详细），因此产生嵌套复杂度
         */
        do {
            if (isFirst) {
                isFirst = false;
            } else {
                pageIndex++;
            }
            String postData = "" +
                    "{\n" +
                    "  \"accessToken\": \"" + accountToken + "\",\n" +
                    "  \"isEncrypt\": " + false + ",\n" +
                    "  \"random\": \"" + random + "\",\n" +
                    "  \"timestamp\": \"" + timestamp + "\",\n" +
                    "  \"param\": {\n" +
                    "    \"pageIndex\": " + pageIndex + ",\n" +
                    "    \"pageSize\": " + pageSize + ",\n" +
                    "    \"bookStartTime\": \"" + "2022-01-01" + "\",\n" +
                    "    \"bookEndTime\": \"" + "2022-01-31" + "\",\n" +
                    "    \"queryTravelType\": " + 0 + "\n" +
                    "  }\n" +
                    "}";

            // 先将post提交的数据原文算出md5
            String postDataMd5 = getMd5(postData);

            // json格式检测(validate = true表示正确)
            JsonValidator jsonValidator = new JsonValidator();
            boolean validate = jsonValidator.validate(postData);
            if (!validate) {
                log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postData);
            }

            // 再计算 sign
            String sign = getMd5(postDataMd5 + secret);

            // get方式提交sign
            String url = "http://api.qa.dttrip.cn/openapi/api/DomesticFlight/GetFlightOrderList?sign=" + sign;

            // 请求接口
            result = postData(postData, url);

            JSONObject jsonObject = JSON.parseObject(result);
            if (jsonObject != null) {
                JSONObject data = jsonObject.getJSONObject("data");
                String errorMessage = (String) jsonObject.get("errorMessage");
                if (data != null) {
                    JSONArray flightOrderList = data.getJSONArray("flightOrderList");
                    JSONObject pageInfo = data.getJSONObject("pageInfo");
                    pageCount = pageInfo.getInteger("pageCount");
                    boolean syncResult = (boolean) jsonObject.get("success");
                    if (syncResult) {
                        int size = flightOrderList.size();
                        for (int i = 0; i < size; i++) {
                            JSONObject subJsonObject = flightOrderList.getJSONObject(i);
                            String orderSerialNo = (String) subJsonObject.get("orderSerialNo");
                            String originalOrderNo = (String) subJsonObject.get("originalOrderNo");

                            // 获取机票订单详情
                            String postDataSub = "" +
                                    "{\n" +
                                    "  \"accessToken\": \"" + accountToken + "\",\n" +
                                    "  \"isEncrypt\": " + false + ",\n" +
                                    "  \"random\": \"" + random + "\",\n" +
                                    "  \"timestamp\": \"" + timestamp + "\",\n" +
                                    "  \"param\": {\n" +
                                    "    \"orderSerialNo\": " + orderSerialNo + "\n" +
                                    "  }\n" +
                                    "}";

                            // 先将post提交的数据原文算出md5
                            String postDataMd5Sub = getMd5(postDataSub);

                            // json格式检测(validate = true表示正确)
                            boolean validateSub = jsonValidator.validate(postDataSub);
                            if (!validateSub) {
                                log.info("❌❌❌❌json格式校验失败，不合法:{}❌❌❌❌", postDataSub);
                            }

                            // 再计算 sign
                            String signSub = getMd5(postDataMd5Sub + secret);

                            // get方式提交sign
                            String urlSub = "http://api.qa.dttrip.cn/openapi/api/DomesticFlight/GetFlightOrderList?sign=" + signSub;

                            // 请求接口
                            resultSub = postData(postDataSub, urlSub);

                            JSONObject jsonObject1 = JSON.parseObject(resultSub);
                            if (jsonObject1 != null) {
                                JSONObject data1 = jsonObject1.getJSONObject("data");
                                String errorMessage1 = (String) jsonObject1.get("errorMessage");
                            }
                        }
                    } else {
                        String errorCode = (String) jsonObject.get("errorCode");
                        log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                    }
                } else {
                    String errorCode = (String) jsonObject.get("errorCode");
                    log.info("❌❌❌获取对账单列表失败，异常信息:{}❌❌❌", errorCode + " : " + errorMessage);
                }
            } else {
                log.info("❌❌❌获取对账单列表失败，异常信息:{请求异常}❌❌❌");
            }

        } while (pageIndex < pageCount);

        return 0;
    }

    public static String getAccessToken() {
        String url = "http://api.qa.dttrip.cn/openapi/api/OAuth/GetAccessToken";
        UUID uuid = UUID.randomUUID();
        String random = uuid.toString();
        String timestamp = Long.toString(System.currentTimeMillis());

        String postData = "{ \"random\": \"" + random + "\", \"timestamp\": \"" + timestamp
                + "\", \"param\": { \"account\": \"" + account + "\", \"password\": \"" + password + "\" }}";
        String result = postData(postData, url);

        //System.out.println("GetAccessToken Result :" + result);

        String accessToken = result.split("accessToken\":\"")[1].split("\",")[0];

        return accessToken;
    }

    public static String postData(String postData, String urlStr) {

        String result = "";
        BufferedReader in = null;
        try {
            String IP_AdRESS = urlStr;
            String urlNameString = IP_AdRESS;
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(25000);
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setRequestProperty("Content-Type", "application/json-patch+json");
            String dataparam = postData;
            OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            out.write(dataparam);
            out.flush();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    public static String getMd5(String plainText) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0) {
                    i += 256;
                }
                if (i < 16) {
                    buf.append("0");
                }
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    public SameRoadApplyOrderSyncMaintain convertCurrencyInfo(String sequenceNo, String travelApplyNo){
        SameRoadApplyOrderSyncMaintain sameRoadApplyOrderSyncMaintain = new SameRoadApplyOrderSyncMaintain();
        String uuid= UUID.randomUUID().toString().replaceAll("-","");
        sameRoadApplyOrderSyncMaintain.setId(uuid);
        sameRoadApplyOrderSyncMaintain.setName(sequenceNo + "_" + travelApplyNo);
        sameRoadApplyOrderSyncMaintain.setCreater("");
        sameRoadApplyOrderSyncMaintain.setCreatedDeptId("");
        sameRoadApplyOrderSyncMaintain.setOwner("");
        sameRoadApplyOrderSyncMaintain.setOwnerDeptId("");
        sameRoadApplyOrderSyncMaintain.setCreatedTime(new Date());
        sameRoadApplyOrderSyncMaintain.setModifier("");
        sameRoadApplyOrderSyncMaintain.setModifiedTime(new Date());
        sameRoadApplyOrderSyncMaintain.setSequenceStatus("COMPLETED");
        sameRoadApplyOrderSyncMaintain.setOwnerDeptQueryCode("1");
        sameRoadApplyOrderSyncMaintain.setOutTravelApplyNo(sequenceNo);
        sameRoadApplyOrderSyncMaintain.setTravelApplyNo(travelApplyNo);
        return sameRoadApplyOrderSyncMaintain;
    }

    public NoteFlightOrderPushBack makeNoteFlightOrderPushBackModel(){
        NoteFlightOrderPushBack noteFlightOrderPushBack = new NoteFlightOrderPushBack();
        String uuid= UUID.randomUUID().toString().replaceAll("-","");
        noteFlightOrderPushBack.setId(uuid);
        noteFlightOrderPushBack.setCreater("");
        noteFlightOrderPushBack.setCreatedDeptId("");
        noteFlightOrderPushBack.setOwner("");
        noteFlightOrderPushBack.setOwnerDeptId("");
        noteFlightOrderPushBack.setCreatedTime(new Date());
        noteFlightOrderPushBack.setModifier("");
        noteFlightOrderPushBack.setModifiedTime(new Date());
        noteFlightOrderPushBack.setSequenceStatus("COMPLETED");
        noteFlightOrderPushBack.setOwnerDeptQueryCode("1");
        return noteFlightOrderPushBack;
    }

//    public NoteStatementPageList makeNoteStatementPageList(){
//        NoteStatementPageList noteStatementPageList = new NoteStatementPageList();
//        String uuid= UUID.randomUUID().toString().replaceAll("-","");
//        noteStatementPageList.setId(uuid);
//        noteStatementPageList.setCreater("");
//        noteStatementPageList.setCreatedDeptId("");
//        noteStatementPageList.setOwner("");
//        noteStatementPageList.setOwnerDeptId("");
//        noteStatementPageList.setCreatedTime(new Date());
//        noteStatementPageList.setModifier("");
//        noteStatementPageList.setModifiedTime(new Date());
//        noteStatementPageList.setSequenceStatus("COMPLETED");
//        noteStatementPageList.setOwnerDeptQueryCode("1");
//        return noteStatementPageList;
//    }
}
